package com.trust.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.trust.agri.exception.ServiceException;
import com.trust.agri.util.BeanUtil;
import com.trust.entity.*;
import com.trust.entity.DTO.FieldDTO;
import com.trust.entity.Param.FieldListParam;
import com.trust.entity.VO.FieldListVO;
import com.trust.mapper.FieldMapper;
import com.trust.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


@Slf4j
@Service
public class FieldServiceImpl extends ServiceImpl<FieldMapper, Field> implements FieldService {

    @Resource
    private FieldPlantLandService fieldPlantLandService;

    @Resource
    private SystemPersonService systemPersonService;

    @Resource
    private SystemDepartmentService systemDepartmentService;

    @Resource
    private SetupLandService setupLandService;

    @Resource
    private DictionaryService dictionaryService;

    @Resource
    private FieldConsumableService fieldConsumableService;

    @Resource
    private FieldInsectService fieldInsectService;

    @Resource
    private FieldIrrigateService fieldIrrigateService;

    @Resource
    private FieldLandService fieldLandService;

    @Resource
    private FieldManureService fieldManureService;

    @Resource
    private FieldSeedService fieldSeedService;

    @Resource
    private FieldSowService fieldSowService;

    @Resource
    private FieldWeedService fieldWeedService;


    @Override
    public Page<FieldListVO> list(FieldListParam param) {
        LambdaQueryWrapper<Field> wrapper = new LambdaQueryWrapper<>();
        if (null != param.getStartTime() && null != param.getEndTime()){
            wrapper.and(e -> {
                e.or(f -> {
                    f.between(Field::getStartTime, param.getStartTime(), param.getEndTime());
                });
                e.or(f -> {
                    f.between(Field::getEndTime, param.getStartTime(), param.getEndTime());
                });
            });
        }
        if (null != param.getLandId()){
            List<FieldPlantLand> plantLandList = fieldPlantLandService.getByLandId(param.getLandId());
            if (CollectionUtil.isEmpty(plantLandList)){
                return null;
            }
            List<Integer> collect = plantLandList.stream().map(FieldPlantLand::getFieldId).collect(Collectors.toList());
            wrapper.in(Field::getId, collect);
        }
        wrapper.orderByDesc(Field::getId);
        Page<Field> page = this.page(new Page<>(param.getPageNum(), param.getPageSize()), wrapper);
        Page<FieldListVO> targetPage = BeanUtil.sourcePage2targetPage(page, FieldListVO.class);
        for (FieldListVO record : targetPage.getRecords()) {
            record.setPrincipalName(null == record.getPrincipalId() ? null : systemPersonService.getNameById(record.getPrincipalId()));
            record.setWorkGroupName(null == record.getWorkGroupId() ? null : systemDepartmentService.getNameById(record.getWorkGroupId()));
            record.setPrincipalName(null == record.getPrincipalId() ? null : systemPersonService.getNameById(record.getPrincipalId()));
            record.setRecorderName(null == record.getRecoder() ? null : systemPersonService.getNameById(record.getRecoder()));
            List<FieldPlantLand> plantLandList = fieldPlantLandService.getByFieldId(record.getId());
            StringBuilder s = new StringBuilder();
            for (FieldPlantLand plantLand : plantLandList) {
                s.append(setupLandService.getCodeById(plantLand.getLandId()) + ",");
            }
            record.setLandId(StringUtils.isNotBlank(s) ? s.substring(0, s.length() - 1) : "");
        }
        return targetPage;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Field saveAndUpdate(FieldDTO param) {
        if (param.getStartTime().after(param.getEndTime())){
            throw new ServiceException("开始时间不能晚于结束时间");
        }
        Field field = BeanUtil.source2target(param, new Field());
        field.setLandId(JSON.toJSONString(param.getLandIds()));
        //作业项目
        if (null == param.getActivityId() && StringUtils.isNotBlank(param.getActivityName())){
            field.setActivityId(dictionaryService.save(79, param.getActivityName()));
        }
        this.saveOrUpdate(field);
        fieldPlantLandService.removeByFieldId(field.getId());
        for (Integer landId : param.getLandIds()) {
            FieldPlantLand plantLand = new FieldPlantLand(landId, field.getId());
            fieldPlantLandService.save(plantLand);

            SetupLand land = setupLandService.getById(landId);
            land.setCurrentFarmingId(field.getId());
            //land.setColor(param.getColor());
            setupLandService.updateById(land);
        }

        if (null != param.getId()){
            fieldConsumableService.removeByFieldId(field.getId());
            this.removeObjectById(field.getId());
        }

        if (CollectionUtil.isNotEmpty(param.getConsumableList())){
            for (FieldConsumable fieldConsumable : param.getConsumableList()) {
                fieldConsumable.setFieldId(field.getId());
                fieldConsumableService.save(fieldConsumable);
            }
        }

        switch (param.getActivityId()){
            case 80:
                FieldLand fieldLand = JSONObject.parseObject(JSONObject.toJSONString(param.getOperate()), FieldLand.class);
                fieldLand.setFieldId(field.getId());
                if (null == fieldLand.getWayId() && StringUtils.isNotBlank(fieldLand.getWayName())){
                    fieldLand.setWayId(dictionaryService.save(154, fieldLand.getWayName()));
                }
                if (null == fieldLand.getHandId() && StringUtils.isNotBlank(fieldLand.getHandName())){
                    fieldLand.setHandId(dictionaryService.save(155, fieldLand.getHandName()));
                }
                fieldLandService.save(fieldLand);
                break;
            case 81:
                FieldSeed fieldSeed = JSONObject.parseObject(JSONObject.toJSONString(param.getOperate()), FieldSeed.class);
                fieldSeed.setFieldId(field.getId());
                if (null == fieldSeed.getSelectWayId() && StringUtils.isNotBlank(fieldSeed.getSelectWayName())){
                    fieldSeed.setSelectWayId(dictionaryService.save(159, fieldSeed.getSelectWayName()));
                }
                fieldSeedService.save(fieldSeed);
                break;
            case 82:
                FieldSow fieldSow = JSONObject.parseObject(JSONObject.toJSONString(param.getOperate()), FieldSow.class);
                fieldSow.setFieldId(field.getId());
                if (null == fieldSow.getWayId() && StringUtils.isNotBlank(fieldSow.getWayName())){
                    fieldSow.setWayId(dictionaryService.save(156, fieldSow.getWayName()));
                }
                fieldSowService.save(fieldSow);
                break;
            case 83:
                FieldIrrigate fieldIrrigate = JSONObject.parseObject(JSONObject.toJSONString(param.getOperate()), FieldIrrigate.class);
                fieldIrrigate.setFieldId(field.getId());
                if (null == fieldIrrigate.getWayId() && StringUtils.isNotBlank(fieldIrrigate.getWayName())){
                    fieldIrrigate.setWayId(dictionaryService.save(165, fieldIrrigate.getWayName()));
                }
                if (null == fieldIrrigate.getWaterId() && StringUtils.isNotBlank(fieldIrrigate.getWaterName())){
                    fieldIrrigate.setWaterId(dictionaryService.save(175, fieldIrrigate.getWaterName()));
                }
                fieldIrrigateService.save(fieldIrrigate);
                break;
            case 84:
                FieldWeed fieldWeed = JSONObject.parseObject(JSONObject.toJSONString(param.getOperate()), FieldWeed.class);
                fieldWeed.setFieldId(field.getId());
                if (null == fieldWeed.getRankGrass() && StringUtils.isNotBlank(fieldWeed.getRankGrassName())){
                    fieldWeed.setRankGrass(dictionaryService.save(170, fieldWeed.getRankGrassName()));
                }
                if (null == fieldWeed.getWayId() && StringUtils.isNotBlank(fieldWeed.getWayName())){
                    fieldWeed.setWayId(dictionaryService.save(173, fieldWeed.getWayName()));
                }
                if (null == fieldWeed.getHarmLevelId() && StringUtils.isNotBlank(fieldWeed.getHarmLevelName())){
                    fieldWeed.setHarmLevelId(dictionaryService.save(172, fieldWeed.getHarmLevelName()));
                }
                fieldWeedService.save(fieldWeed);
                break;
            case 85:
                FieldManure fieldManure = JSONObject.parseObject(JSONObject.toJSONString(param.getOperate()), FieldManure.class);
                fieldManure.setFieldId(field.getId());
                if (null == fieldManure.getWayId() && StringUtils.isNotBlank(fieldManure.getWayName())){
                    fieldManure.setWayId(dictionaryService.save(157, fieldManure.getWayName()));
                }
                if (null == fieldManure.getTypeId() && StringUtils.isNotBlank(fieldManure.getTypeName())){
                    fieldManure.setTypeId(dictionaryService.save(158, fieldManure.getTypeName()));
                }
                fieldManureService.save(fieldManure);
                break;
            case 86:
                FieldInsect fieldInsect = JSONObject.parseObject(JSONObject.toJSONString(param.getOperate()), FieldInsect.class);
                fieldInsect.setFieldId(field.getId());
                if (null == fieldInsect.getKind() && StringUtils.isNotBlank(fieldInsect.getKindName())){
                    fieldInsect.setKind(dictionaryService.save(160, fieldInsect.getKindName()));
                }
                if (null == fieldInsect.getDrug() && StringUtils.isNotBlank(fieldInsect.getDrugName())){
                    fieldInsect.setDrug(dictionaryService.save(161, fieldInsect.getDrugName()));
                }
                if (null == fieldInsect.getWayId() && StringUtils.isNotBlank(fieldInsect.getWayName())){
                    fieldInsect.setWayId(dictionaryService.save(162, fieldInsect.getWayName()));
                }
                if (null == fieldInsect.getDegreeId() && StringUtils.isNotBlank(fieldInsect.getDegreeName())){
                    fieldInsect.setDegreeId(dictionaryService.save(163, fieldInsect.getDegreeName()));
                }
                if (null == fieldInsect.getHarmPart() && StringUtils.isNotBlank(fieldInsect.getHarmPartName())){
                    fieldInsect.setHarmPart(dictionaryService.save(164, fieldInsect.getHarmPartName()));
                }
                fieldInsectService.save(fieldInsect);
                break;
            default:
                break;
        }
        return field;
    }


    @Override
    public List<Object> fieldActivityKey() {
        List<Object> list = new ArrayList<>();
        list.add(new FieldInsect());
        list.add(new FieldIrrigate());
        list.add(new FieldLand());
        list.add(new FieldManure());
        list.add(new FieldSeed());
        list.add(new FieldSow());
        list.add(new FieldWeed());
        return list;
    }


    private void removeObjectById(Integer id) {
        fieldInsectService.removeByFieldId(id);
        fieldIrrigateService.removeByFieldId(id);
        fieldLandService.removeByFieldId(id);
        fieldManureService.removeByFieldId(id);
        fieldSeedService.removeByFieldId(id);
        fieldSowService.removeByFieldId(id);
        fieldWeedService.removeByFieldId(id);
    }
}
